<template>
  <div>
    <el-form
      :inline="true"
    >
      <el-form-item>
        <el-button
          v-show="mList.length > 0"
          icon="el-icon-document"
          type="primary"
          @click="dialogCopyFormVisible = true"
        >{{ $t('copy') }}
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-select v-model="templateType" @change="changeType">
          <el-option :label="$t('explain')" value="explain"/>
          <el-option :label="$t('device')" value="device"/>
          <el-option :label="$t('setting')" value="setting"/>
          <el-option :label="$t('param')" value="param"/>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-input
          v-model="name"
          clearable
          :placeholder="$t('name')"
          @change="changeType"
        />
      </el-form-item>
      <el-button
        type="primary"
        @click="changeType"
      >{{ $t('search') }}
      </el-button>
      <el-form-item/>
      <el-form-item>
        <el-button
          type="primary"
          @click="showAdd"
        >{{ $t('add') }}
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          @click="download"
        >{{ $t('download') }}
        </el-button>
      </el-form-item>
    </el-form>
    <div class="uni-scroll" style="height: calc(100vh - 220px)">
      <el-table
        v-if="!loading"
        ref="multipleTable"
        :data="productTemplateList"
        style="width: 100%;"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="50"/>
        <el-table-column width="50">
          <template slot-scope="scope">
            <el-image
              :src="scope.row.iconUrl"
              style="width: 25px;height: 25px"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="templateType!=='device'" :label="$t('name')">
          <template slot-scope="scope">
            <span @click="dictionaries(scope.row)">{{ scope.row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column v-if="templateType==='device'" prop="protocol" :label="$t('protocol')"/>
        <el-table-column prop="keyName" :label="$t('keyName')"/>
        <el-table-column v-if="templateType!=='device'" prop="value" :label="$t('value')"/>
        <el-table-column v-if="templateType!=='device'" prop="unit" :label="$t('unit')"/>
        <el-table-column

          v-if="templateType ==='explain' || templateType === 'setting'"
          :label="$t('type')"
        >
          <template slot-scope="scope">
            <span v-if="templateType==='explain'" style="margin-left: 13px">{{
                formatExplainType(scope.row.type)
              }}</span>
            <span v-else-if="templateType==='setting'" style="margin-left: 13px">{{
                formatSettingType(scope.row.type)
              }}</span>
          </template>
        </el-table-column>
        <el-table-column v-if="templateType!=='device'" :label="$t('hidden')">
          <template slot-scope="scope">
            <el-switch
              v-model="scope.row.hidden"
              disabled
            />
          </template>
        </el-table-column>
        <el-table-column v-if="templateType!=='param'" :label="$t('linkage')">
          <template slot-scope="scope">
            <el-switch
              v-model="scope.row.canDeviceLinkage"
              disabled
            />
          </template>
        </el-table-column>
        <el-table-column v-if="templateType!=='device' && templateType!=='param'" :label="$t('rank')">
          <template slot-scope="scope">
            <span>{{ scope.row.rankNumber }}</span>
          </template>
        </el-table-column>
        <el-table-column width="180" :label="$t('function')">
          <template slot-scope="scope">
            <el-button
              v-if="templateType === 'setting' && scope.row.type === 'fixedParam'"
              type="text"
              icon="el-icon-thumb"
              @click="showSettingParam(scope.row)"
            >{{ $t('param') }}
            </el-button>
            <el-button
              v-if="templateType === 'explain'"
              type="text"
              icon="el-icon-edit-outline"
              @click="showExplainEval(scope.row)"
            >{{ $t('script') }}
            </el-button>
            <el-button
              v-if="templateType === 'explain'"
              type="text"
              icon="el-icon-warning"
              @click="showExplainWarnEval(scope.row)"
            >{{ $t('warn') + $t('script') }}
            </el-button>
            <el-button
              type="text"
              icon="el-icon-edit"
              @click="edit(scope.row)"
            >{{ $t('edit') }}
            </el-button>
            <el-button
              style="color: #f56c6c"
              type="text"
              icon="el-icon-delete"
              @click="del(scope.row)"
            >{{ $t('delete') }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <el-dialog
      :visible.sync="dialogFormVisible"
    >
      <el-form
        label-width="120px"
        :model="productTemplate"
      >
        <el-form-item v-if="templateType!=='device'" :label="$t('name')">
          <el-input v-model="productTemplate.name" :disabled="productTemplate.templateId"/>
        </el-form-item>
        <el-form-item :label="$t('keyName')">
          <el-input v-model="productTemplate.keyName" :disabled="productTemplate.templateId"/>
        </el-form-item>
        <el-form-item v-if="templateType==='device'" :label="$t('protocol')">
          <el-autocomplete
            v-model="productTemplate.protocol"
            class="inline-input"
            :fetch-suggestions="queryProtocolSearch"
          />
        </el-form-item>
        <el-form-item :label="$t('remark')">
          <el-input v-model="productTemplate.remark"/>
        </el-form-item>
        <el-form-item :label="$t('value')">
          <el-input v-model="productTemplate.value"/>
        </el-form-item>
        <el-form-item :label="$t('rank')">
          <el-input v-model="productTemplate.rankNumber"/>
        </el-form-item>
        <el-form-item :label="$t('unit')">
          <el-input v-model="productTemplate.unit"/>
        </el-form-item>
        <el-form-item :label="$t('icon')">
          <el-input v-model="productTemplate.iconUrl">
            <template slot="prepend">
              <el-image
                style="width: 23px;height: 23px"
                :src="productTemplate.iconUrl"
              />
            </template>
            <template slot="append">
              <i class="el-icon-caret-bottom" @click="choseIcon"/>
            </template>
          </el-input>
          <div v-show="isIconOpen">
            <div v-if="templateType === 'explain'">
              <el-image
                v-for="(item,index) in sensorIconList"
                :key="index"
                style="cursor: pointer;width: 35px;height: 35px;margin: 5px"
                :src="item.url"
                @click="changeIco(item.url,200145308)"
              />
            </div>
            <div v-else-if="templateType === 'device'">
              <el-image
                v-for="(item,index) in deviceIconList"
                :key="index"
                style="cursor: pointer;width: 35px;height: 35px;margin: 5px"
                :src="item.url"
                @click="changeIco(item.url,200145308)"
              />
            </div>
            <div v-else-if="templateType === 'setting'">
              <el-image
                v-for="(item,index) in settingIconList"
                :key="index"
                style="cursor: pointer;width: 35px;height: 35px;margin: 5px"
                :src="item.url"
                @click="changeIco(item.url,200145308)"
              />
            </div>
            <div v-else-if="templateType === 'param'">
              <el-image
                v-for="(item,index) in paramIconList"
                :key="index"
                style="cursor: pointer;width: 35px;height: 35px;margin: 5px"
                :src="item.url"
                @click="changeIco(item.url,200145308)"
              />
            </div>
          </div>
        </el-form-item>
        <el-form-item
          v-if="templateType === 'explain'"
          :label="$t('script')"
        >
          <el-select v-model="productTemplate.templateEvalId">
            <el-option
              v-for="item in productTemplateExplainEvalList"
              :key="item.templateEvalId"
              :label="item.name"
              :value="item.templateEvalId"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="templateType === 'explain'"
          :label="$t('explain')+$t('type')"
          @change="formExplainTypeChange"
        >
          <el-select v-model="productTemplate.type">
            <el-option :label="$t('static')" value="static"/>
            <el-option :label="$t('line')" value="line"/>
            <el-option :label="$t('string')" value="string"/>
          </el-select>
        </el-form-item>
        <el-form-item
          v-else-if="templateType === 'setting'"
          :label="$t('setting')+$t('type')"
        >
          <el-select
            v-model="productTemplate.type"
            @change="formSettingTypeChange"
          >
            <el-option v-for="(item,index) in settingTypeList" :key="index" :label="item.label" :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="templateType !== 'param'"
          :label="$t('device')+$t('linkage')"
        >
          <el-switch
            v-model="productTemplate.canDeviceLinkage"
          />
        </el-form-item>
        <el-form-item
          :label="$t('hidden')"
        >
          <el-switch
            v-model="productTemplate.hidden"
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">{{ $t('cancel') }}</el-button>
        <el-button type="primary" @click="addOrUpdate">{{ $t('confirm') }}</el-button>
      </div>
    </el-dialog>

    <el-dialog
      :title="$t('copy')"
      :visible.sync="dialogCopyFormVisible"
    >
      <el-form
        label-width="120px"
        :model="productTemplate"
      >
        <el-form-item :label="$t('product')">
          <el-select v-model="productTemplate.productId" @change="formProductChange">
            <el-option
              v-for="item in productList"
              :key="item.productId"
              :label="item.name"
              :value="item.productId"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogCopyFormVisible = false">{{ $t('cancel') }}</el-button>
        <el-button type="primary" @click="copy">{{ $t('confirm') }}</el-button>
      </div>
    </el-dialog>

    <el-dialog
      :title="productTemplate.keyName"
      :visible.sync="dialogDictionariesVisible"
    >
      <dictionaries-model v-if="dialogDictionariesVisible" :product-id="productTemplate.productId"
                          :template-type="templateType" :key-name="productTemplate.keyName"
                          @change="listProductTemplate"
      />
    </el-dialog>

    <el-dialog
      :title="productTemplate.name"
      :visible.sync="dialogSettingParamVisible"
    >
      <template-setting-param v-if="dialogSettingParamVisible" :template-id="productTemplate.templateId"
                              :product-id="productId" :key-name="productTemplate.keyName"
      />
    </el-dialog>

    <el-dialog
      :title="productTemplate.name"
      :visible.sync="dialogExplainEvalVisible"
    >
      <product-template-explain-eval v-if="dialogExplainEvalVisible" :template-id="productTemplate.templateId"
                                     :product-id="productId" :key-name="productTemplate.keyName"
      />
    </el-dialog>

    <el-dialog
      :title="productTemplate.name"
      :visible.sync="dialogExplainWarnEvalVisible"
    >
      <product-template-explain-warn-eval v-if="dialogExplainWarnEvalVisible" :template-id="productTemplate.templateId"
                                          :product-id="productId" :key-name="productTemplate.keyName"
      />
    </el-dialog>

  </div>
</template>

<script>
import {
  cancelNotice,
  failureNotice,
  formatDate,
  formatExplainType,
  formatSettingType,
  listSettingType,
  successNotice
} from '@/util/common'
import {
  copyProductTemplateExplain,
  deleteProductTemplateExplain,
  insertProductTemplateExplain,
  listProductTemplateExplain,
  updateProductTemplateExplain
} from '@/api/iot/iotProductTemplateExplainApi'
import {
  copyProductTemplateSetting,
  deleteProductTemplateSetting,
  insertProductTemplateSetting,
  listProductTemplateSetting,
  updateProductTemplateSetting
} from '@/api/iot/iotProductTemplateSettingApi'
import {
  copyProductTemplateParam,
  deleteProductTemplateParam,
  insertProductTemplateParam,
  listProductTemplateParam,
  updateProductTemplateParam
} from '@/api/iot/iotProductTemplateParamApi'
import {
  copyProductTemplateDevice,
  deleteProductTemplateDevice,
  insertProductTemplateDevice,
  listProductTemplateDevice,
  updateProductTemplateDevice
} from '@/api/iot/iotProductTemplateDeviceApi'
import { listProduct } from '@/api/iot/iotProductApi'
import { listSensorIcon } from '@/api/iot/iotDeviceSensorApi'
import { listDeviceIcon } from '@/api/iot/iotDeviceApi'
import { listDeviceSettingIcon } from '@/api/iot/iotDeviceSettingApi'
import { listDeviceParamIcon } from '@/api/iot/iotDeviceParamApi'
import { getCompanyId } from '@/util/storage'
import DictionariesModel from '../DictionariesModel'
import TemplateSettingParam from '../TemplateSettingParam'
import { downloadExcel } from '@/util/file'
import ProductTemplateExplainEval from '@/components/ProductTemplateExplainEval'
import ProductTemplateExplainWarnEval from '@/components/ProductTemplateExplainWarnEval'
import { listProductTemplateExplainEval } from '@/api/iot/iotProductTemplateExplainEvalApi'
import { listCodec } from '@/api/iot/iotCodecApi'

export default {
  name: 'ProductTemplate',
  components: {
    DictionariesModel,
    TemplateSettingParam,
    ProductTemplateExplainEval,
    ProductTemplateExplainWarnEval
  },
  props: {
    productId: {
      type: Number,
      default: null
    }
  },
  data() {
    return {
      productTemplateList: [],
      templateType: 'explain',
      name: null,
      mList: [],
      productList: [],
      companyId: getCompanyId(),
      dialogFormVisible: false,
      dialogSettingParamVisible: false,
      dialogExplainEvalVisible: false,
      dialogExplainWarnEvalVisible: false,
      productTemplate: {
        name: null,
        keyName: null,
        productId: null,
        value: null,
        templateId: null,
        remark: null,
        iconUrl: null,
        unit: null,
        type: null,
        canDeviceLinkage: true
      },

      dialogDictionariesVisible: false,
      dialogCopyFormVisible: false,
      isIconOpen: false,
      deviceIconList: [],
      paramIconList: [],
      sensorIconList: [],
      settingIconList: [],
      settingTypeList: [],
      loading: false,
      productTemplateExplainEvalList: [],
      protocolList: [],
    }
  },
  mounted() {
    this.listCodec()
    this.initIcon()
    this.listProduct()
    this.settingTypeList = listSettingType(this)
  },
  methods: {
    queryProtocolSearch(queryString, cb) {
      const protocolList = this.protocolList
      const results = queryString ? protocolList.filter(this.createProtocolFilter(queryString)) : protocolList
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    createProtocolFilter(queryString) {
      return (restaurant) => {
        return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
      }
    },
    listCodec() {
      listCodec().then(res => {
        const { code, data } = res
        const protocolList = []
        if (code === '200') {
          data.forEach(item => {
            this.productTemplate.protocol = item
            protocolList.push({
              label: item,
              value: item
            })
          })
        }
        this.protocolList = protocolList
      })
    },
    listProductTemplateExplainEval() {
      listProductTemplateExplainEval({
        templateId: this.productTemplate.templateId
      }).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.productTemplateExplainEvalList = data
        } else {
          this.productTemplateExplainEvalList = []
        }
        this.productTemplateExplainEvalList.unshift({
          templateEvalId: 0,
          name: this.$t('empty')
        })
      })
    },
    download() {
      const downloadData = []
      const downloadColumnNameList = [
        this.$t('name'),
        this.$t('keyName'),
        this.$t('unit'), this.$t('explain') + ' / ' + this.$t('setting') + this.$t('type'),
        this.$t('hidden'),
        this.$t('linkage')
      ]
      for (let i = 0, j = this.productTemplateList.length; i < j; i++) {
        const template = this.productTemplateList[i]
        let typeString
        switch (this.templateType) {
          case 'explain':
            typeString = this.formatExplainType(template.type)
            break
          case 'setting':
            typeString = this.formatSettingType(template.type)
            break
          default:
            typeString = ''
        }
        downloadData.push({
          name: template.name,
          keyName: template.keyName,
          unit: template.unit,
          type: typeString,
          hidden: template.hidden,
          canDeviceLinkage: template.canDeviceLinkage
        })
      }
      downloadExcel(this.productId + '-' + this.templateType, downloadColumnNameList, downloadData)
    },
    formatDate(time) {
      return formatDate(this, time)
    },
    formatSettingType(type) {
      return formatSettingType(this, type)
    },
    formatExplainType(type) {
      return formatExplainType(this, type)
    },
    initIcon() {
      listDeviceParamIcon({}).then(res => {
        if (res.code === '200') {
          this.paramIconList = res.data
        }
      })

      listSensorIcon({}).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.sensorIconList = data
        }
      })

      listDeviceIcon({}).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.deviceIconList = data
        }
      })

      listDeviceSettingIcon({}).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.settingIconList = data
        }
      })
    },
    copy() {
      const param = {
        productId: this.productTemplate.productId,
        idList: this.mList
      }
      let r
      switch (this.templateType) {
        case 'explain':
          r = copyProductTemplateExplain(param)
          break
        case 'setting':
          r = copyProductTemplateSetting(param)
          break
        case 'param':
          r = copyProductTemplateParam(param)
          break
        case 'device':
          r = copyProductTemplateDevice(param)
          break
        default:
          failureNotice(this)
          return
      }
      r.then(res => {
        const { code } = res
        if (code === '200') {
          this.listProductTemplate()
          this.dialogCopyFormVisible = false
        }
      })
    },
    formSettingTypeChange(type) {
      this.productTemplate.type = type
    },
    formExplainTypeChange(type) {
      this.productTemplate.type = type
    },
    changeIco(iconUrl) {
      this.isIconOpen = false
      this.productTemplate.iconUrl = iconUrl
    },
    choseIcon() {
      if (this.isIconOpen) {
        this.isIconOpen = false
      } else {
        this.isIconOpen = true
      }
    },
    showAdd() {
      this.productTemplate = {
        productId: this.productId,
        keyName: null,
        name: null,
        templateId: null,
        remark: null,
        iconUrl: null,
        unit: null,
        value: null,
        type: null
      }
      this.dialogFormVisible = true
    },
    dictionaries(item) {
      this.productTemplate = item
      this.dialogDictionariesVisible = true
    },
    edit(item) {
      this.productTemplate = item
      if (this.templateType === 'explain') {
        this.listProductTemplateExplainEval()
      }
      this.dialogFormVisible = true
    },
    showSettingParam(item) {
      this.productTemplate = item
      this.dialogSettingParamVisible = true
    },
    showExplainEval(item) {
      this.productTemplate = item
      this.dialogExplainEvalVisible = true
    },
    showExplainWarnEval(item) {
      this.productTemplate = item
      this.dialogExplainWarnEvalVisible = true
    },
    addOrUpdate() {
      const json = {
        ...this.productTemplate
      }
      let r
      if (!this.productTemplate.templateId) {
        switch (this.templateType) {
          case 'explain':
            r = insertProductTemplateExplain(json)
            break
          case 'setting':
            r = insertProductTemplateSetting(json)
            break
          case 'param':
            r = insertProductTemplateParam(json)
            break
          case 'device':
            r = insertProductTemplateDevice(json)
            break
          default:
            failureNotice(this)
        }
      } else {
        switch (this.templateType) {
          case 'explain':
            r = updateProductTemplateExplain(json)
            break
          case 'setting':
            r = updateProductTemplateSetting(json)
            break
          case 'param':
            r = updateProductTemplateParam(json)
            break
          case 'device':
            r = updateProductTemplateDevice(json)
            break
          default:
            failureNotice(this)
        }
      }
      r.then(res => {
        const { code } = res
        if (code === '200') {
          successNotice(this)
        }
        this.listProductTemplate()
      })
    },
    formProductChange(value) {
      this.productTemplate.productId = value
    },
    productChange(value) {
      this.productId = value
      this.currentPage = 1
      this.listProductTemplate()
    },
    listProduct() {
      listProduct({
        companyId: this.companyId
      }).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.productList = data
          this.listProductTemplate()
        }
      })
    },
    handleSelectionChange(value) {
      const mList = []
      value.forEach(function(row) {
        mList.push(row.templateId)
      })
      this.mList = mList
    },
    del(index) {
      const that = this
      this.$confirm(this.$t('deletePrompt'), this.$t('prompt'), {
        confirmButtonText: this.$t('confirm'),
        cancelButtonText: this.$t('cancel'),
        templateType: 'warning'
      })
        .then(function() {
          let r
          switch (that.templateType) {
            case 'explain':
              r = deleteProductTemplateExplain({
                templateId: index.templateId
              })
              break
            case 'setting':
              r = deleteProductTemplateSetting({
                templateId: index.templateId
              })
              break
            case 'param':
              r = deleteProductTemplateParam({
                templateId: index.templateId
              })
              break
            case 'device':
              r = deleteProductTemplateDevice({
                templateId: index.templateId
              })
              break
            default:
              failureNotice(that)
          }
          r.then(res => {
            const { code } = res
            if (code === '200') {
              that.listProductTemplate()
            }
          })
        })
        .catch(function() {
          cancelNotice(that)
        })
    },
    changeType() {
      this.currentPage = 0
      this.listProductTemplate()
    },
    listProductTemplate() {
      this.loading = true
      let r
      switch (this.templateType) {
        case 'explain':
          r = listProductTemplateExplain({
            productId: this.productId
          })
          break
        case 'setting':
          r = listProductTemplateSetting({
            productId: this.productId
          })
          break
        case 'param':
          r = listProductTemplateParam({
            productId: this.productId
          })
          break
        case 'device':
          r = listProductTemplateDevice({
            productId: this.productId
          })
          break
        default:
          failureNotice(this)
      }
      r.then(res => {
        const { code, data } = res
        if (code === '200') {
          if (this.name != null && this.name !== '') {
            const productTemplateList = []
            data.forEach(template => {
              if (template.name.indexOf(this.name) !== -1 || template.keyName.indexOf(this.name) !== -1) {
                productTemplateList.push(template)
              }
            })
            this.productTemplateList = productTemplateList
          } else {
            this.productTemplateList = data
          }
        }
        this.loading = false
      })
    }
  }
}
</script>
